package com.lngsyz.eseal.base;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.lngsyz.eseal.base.biz.service.NotLoginService;
import com.lngsyz.eseal.base.biz.service.RedisService;
import com.lngsyz.eseal.base.entity.CommonConstant;
import com.lngsyz.eseal.base.entity.LoginInfo;
import com.lngsyz.eseal.base.entity.URICommonResult;
import com.lngsyz.eseal.base.util.jwt.TokenUtil;

/**
 * 拦截器
 * 
 * @author Administrator
 *
 */
public class MyInterceptor implements HandlerInterceptor {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class);

	private NotLoginService notLoginService = SpringUtil.getBean(NotLoginService.class);
	
	private RedisService redisService = SpringUtil.getBean(RedisService.class);

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
		// 解决跨域
		String origin = request.getHeader("Origin");
		response.setHeader("Access-Control-Allow-Origin", origin);
		response.setHeader("Access-Control-Allow-Methods", "*");
		response.setHeader("Access-Control-Allow-Headers", "Origin,Content-Type,Authorization,Devicetype,Accept,token,X-Requested-With");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		// 获取token 和 登录设备类型
		String token = request.getHeader(TokenUtil.AUTHORIZATION);
		if(StringUtils.equals(RequestMethod.OPTIONS.toString(), request.getMethod())) {
			return true;
		}
		String requestURI = request.getRequestURI();
		LoginInfo loginInfo = new LoginInfo();
		if (StringUtils.indexOf(requestURI.toLowerCase(), "notlogin") > -1) {
			// 不需要登录，不做校验 
		} else {
			// 不是登录请求，并且token值为空，报异常
			if (StringUtils.isBlank(token)) {
				URICommonResult result = new URICommonResult();
				result.setCode(CommonConstant.CODE_NO_AUTHORIZATION);
				returnJson(response, result);
				return false;
			} else {
				try {
					loginInfo = notLoginService.decodeLoginInfoByToken(token);
					if(StringUtils.indexOf(requestURI, "refreshToken") == -1) {
						redisService.refreshTemp(loginInfo.getId());
					}
				} catch (Exception e) {
					URICommonResult result = new URICommonResult();
					result.setCode(CommonConstant.CODE_TOKEN_INVALID);
					returnJson(response, result);
					return false;
				}
				// 可以正常解析，但是本地存储的token已过期
				if (loginInfo == null) {
					URICommonResult result = new URICommonResult();
					result.setCode(CommonConstant.CODE_TOKEN_EXPIRED);
					returnJson(response, result);
					return false;
				}
			}
			request.setAttribute(TokenUtil.LOGIN_USER, loginInfo);
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {
		// System.out.println("postHandle被调用");
	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, Exception e) throws Exception {
		// System.out.println("afterCompletion被调用");
	}

	/**
	 * 当token过期或无效时，返回错误提示信息
	 * 
	 * @param response
	 * @param rtnJson
	 * @throws Exception
	 */
	private void returnJson(HttpServletResponse response, Object rtnJson) throws Exception {
		PrintWriter writer = null;
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=utf-8");
		try {
			writer = response.getWriter();
			writer.print(JSON.toJSONString(rtnJson));
		} catch (IOException e) {
			LOGGER.error("业务异常信息：[{}]", e.getMessage(), e);
		} finally {
			if (writer != null)
				writer.close();
		}
	}
}